// use easy_sqlx::Table;

use std::{collections::HashMap, vec};

use chrono::Local;
use easy_sqlx::{sync_tables, Table, Where};
use easy_sqlx_core::sql::{
    builder::builder::{ExecuteBuilder, QueryBuilder},
    dialects::page::PageRequest,
};
// use easy_sqlx_core::sql::builder::insert_builder::InsertBuilder;
use easy_sqlx::WhereAppend;
use sqlx::{postgres::PgConnectOptions, Connection, FromRow, PgConnection};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, Layer as _, Registry};

#[derive(Table, Default, Debug, Clone, FromRow)]
#[index(columns("abc"))]
#[table(recreate = "now", from = "User1")]
pub struct User {
    #[col(pk, comment = "主键")]
    pub id: i64,
    #[col(pk, len = 100, column = "abc", comment = "姓名")]
    pub name: String,
    pub blob: Option<Vec<u8>>,
    pub create_time: Option<chrono::NaiveDateTime>,
}

#[derive(Table, Default, Debug, Clone, FromRow)]
#[table(name = "User", query_only)]
pub struct UserSummary {
    pub id: i64,
    pub name: String,
}

impl User {
    // pub fn id(&self) -> i64 {
    //     self.id
    // }

    // pub async fn insert(&self, conn: &mut PgConnection) -> sqlx::Result<PgQueryResult> {
    //     let table = Self::table();
    //     let schema = schema::new::<PgConnection, Postgres>("".to_owned());
    //     let sql = schema.sql_insert(&table);
    //     sqlx::query::<Postgres>(&sql)
    //         .bind(self.id)
    //         .bind(self.name.clone())
    //         .bind(self.create_time)
    //         .execute(conn)
    //         .await.map_err(|err| {
    //             println!("execute {sql} {err}");
    //             err
    //         })
    // }
}

// fn aa<T: AsRef<str>>(a: Vec<T>) {
//     let rea = a.concat();
//     // aa1(a.)
// }

// fn aa1(a: Vec<String>) {
//     let rea = a.concat();
// }

#[tokio::main]
async fn main() {
    let layer = tracing_subscriber::fmt::layer()
        .with_file(true)
        .with_line_number(true)
        .with_filter(tracing_subscriber::filter::LevelFilter::INFO);
    Registry::default().with(layer).init();

    // tracing::debug!("日志 ...");

    let binding = PgConnectOptions::new()
        .host("127.0.0.1")
        .database("prjmgr")
        .username("prjmgr")
        .password("123456");
    // PgConnection::from(value)
    let mut conn = PgConnection::connect_with(&binding).await.unwrap(); // .expect_err("connect database error");
                                                                        // User::id_in(vec![1]);
                                                                        // User::cre
    sync_tables(&mut conn, vec![User::table()]).await.unwrap();

    // println!("UserSimple： {}", UserSummary::table_name());

    // UserSimple::build_insert();
    let u: Vec<User> = User::build_delete()
        .execute_return(&mut conn)
        .await
        .unwrap();
    println!("delete {:?}", u);
    // User::build_delete().execute(&mut conn).await.unwrap();

    let user = User {
        id: 108,
        name: "777".to_string(),
        create_time: Some(Local::now().naive_local()),
        ..Default::default() // ..Default::default()
    };

    user.update().execute(&mut conn).await.unwrap();

    // User::na;

    let u: Vec<User> = user.insert().execute_return(&mut conn).await.unwrap();
    println!("insert {:?}", u);

    let users: Vec<User> = User::select()
        .and(User::id_not_in(vec![106]))
        .and(User::name_eq("111"))
        .all(&mut conn)
        .await
        .unwrap();
    for ele in users {
        println!("ele: {:?}", ele);
    }

    // sqlx::query("").fetch(&mut conn).as_ref().type_id();

    // User::select().count(executor);

    let u: Vec<User> = User::build_update()
        .and(User::id_eq(108))
        .set(User::name("1002220"))
        .execute_return(&mut conn)
        .await
        .unwrap();
    println!("update: {:?}", u);
    // let select = User::select().order_by(User::id_asc());
    // User::name_like(val)
    let wh = Where::new(User::id_gt(0)); // id > 0
    let mut page_result: easy_sqlx_core::sql::dialects::page::PageResult<User> = User::select()
        .and(wh.clone())
        .order_by(User::id_asc())
        .page(&mut conn, &PageRequest::new(10, 1))
        .await
        .unwrap();
    // 统计分页信息
    page_result.set_total(User::select().and(wh).count(&mut conn).await.unwrap());

    // User::build_delete().execute(&mut conn).await.unwrap();

    // println!("{:?}", User::table().columns);

    // // 增加完整记录
    // user.insert().execute(&mut conn).await.unwrap();
    // // println!("{:?}", a);
    // User::id_asc()
    User::build_insert()
        .set(User::id(14))
        .set(User::name("abc".to_string()))
        .set(User::blob(vec![]))
        .execute(&mut conn)
        .await
        .unwrap();

    User::col_id();

    // User::delete_by_id(id, name)

    let v: Option<i64> = User::select()
        .optional_scalar(&mut conn, &User::col_id().min())
        .await
        .unwrap();
    println!("最大值: {}", v.unwrap());

    let umap: HashMap<i64, User> = User::select()
        .map_all(&mut conn, |o: &User| o.id)
        .await
        .unwrap();
    println!("{:?}", umap);
    // let a = user.update();
    // a.execute(&mut conn).await.unwrap();

    // // let a = User::build_select()
    // //     .columns(vec![
    // //         User::col_id().to_string(),
    // //         User::col_name().to_string(),
    // //     ])
    // //     .and(User::id_eq(11))
    // //     .query().fetch(executor)
    // //     .execute(&mut conn)
    // //     .await.unwrap();

    // user.update().execute(&mut conn).await.unwrap();

    // User::build_update()
    //     .set(User::name("007".to_string()))
    //     .and(User::id_eq(7))
    //     .and(User::name_eq("007".to_string()))
    //     .execute(&mut conn)
    //     .await
    //     .unwrap();

    // // User::select_by_id(100, "".to_string());
    // let res: Option<User> = User::select()
    //     .and(User::name_like("%7%".to_string()))
    //     .and(User::id_in(vec![106]))
    //     .optional(&mut conn)
    //     .await
    //     .unwrap();

    // println!("{:?}", res);

    // let c = User::select().count(&mut conn).await.unwrap();
    // println!("count: {c}");

    // let u: User = User::select_by_id(1, "1".to_string())
    //     .one(&mut conn)
    //     .await
    //     .unwrap();
    // println!("{:?}", u);

    // // User::select().and(User::id_eq(1)).one(&mut conn).await.unwrap()

    // user.delete().execute(&mut conn).await.unwrap();

    // let update = User::build_update();
    // update.and(User::id_eq(100));

    // User::create_time(val);
    // User::cre

    // User::

    // User::tes

    // user.insert(&mut conn).await.unwrap();
    // User::insert().await;

    // User::table();
    // println!("table name: {}", User::all_cols().join(","));
    // User::col_name_name();

    // let pair = Pair {
    //     name: User::col_id_name(),
    //     value: Value::Long(1),
    // };
    // pair.value.

    // let ab: sqlx::query::Query<'_, Postgres, PgArguments> = sqlx::query::<Postgres>("");
    // let ay : PgArguments = 0;
    // let e = ab.bind(1);
    // e.execute()

    // sync_tables(conn, tables, default_schema)
    println!("Hello, world!");
}
